package org.covalence.core.visitor;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.covalence.core.ClassConfig;
import org.covalence.core.Strings;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.EmptyVisitor;

public class ClassConfigVisitor extends EmptyVisitor {

	private Map<String, String> fields = 
		new HashMap<String, String>();

	private ClassConfig cc;
	
	private static Logger log = Logger.getLogger(ClassConfigVisitor.class);

	public ClassConfigVisitor(String className) {
		this.cc = new ClassConfig(className);
	}

	@Override
	public FieldVisitor visitField(int access, String name, String desc, 
			String signature, Object value) {
		
		fields.put(name, desc);
		log.trace("[class:" + this.cc.getClassName() +
				", access:" + Strings.access(access) +
				", name:" + name + 
				", desc:" + desc +
				", signature:" + signature + 
				", value:" + value + "]");
		return super.visitField(access, name, desc, signature, value);
	}

	@Override
	public MethodVisitor visitMethod(int access, String name, String desc, 
			String signature, String[] exceptions) {
		
		log.trace("[class:" + this.cc.getClassName() +
				", access:" + Strings.access(access) + 
				", name:" + name + 
				", desc:" + desc +
				", signature:" + signature + 
				", exceptions:" + exceptions + "]");
		if ((access & Opcodes.ACC_STATIC) == 0 && 
				name.startsWith("set") &&
				Type.getArgumentTypes(desc).length == 1) {
			String property = Strings.accessorToProperty(name);
			if (fields.containsKey(property))
				cc.putProperty(property, fields.get(property));
		}
		return super.visitMethod(access, name, desc, signature, exceptions);
	}
	
	public ClassConfig getClassConfig() {
		return cc;
	}
}
